package com.cxyd.modules.wcs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cxyd.common.constant.RcsConstants;
import com.cxyd.common.constant.WcsConstants;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.modules.api.dto.RcsResultYF;
import com.cxyd.modules.log.service.SysLogWorkService;
import com.cxyd.modules.wcs.dao.AgvTrkYfDao;
import com.cxyd.modules.wcs.dto.AgvTrkYfDTO;
import com.cxyd.modules.wcs.dto.AgvTrkYfPostDTO;
import com.cxyd.modules.wcs.entity.AgvTrkYfEntity;
import com.cxyd.modules.wcs.entity.TrkEntity;
import com.cxyd.modules.wcs.service.AgvTrkYfService;
import com.cxyd.modules.wcs.service.TrkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class AgvTrkYfServiceImpl extends CrudServiceImpl<AgvTrkYfDao, AgvTrkYfEntity, AgvTrkYfDTO> implements AgvTrkYfService {
    @Resource
    private TrkService trkService;
    @Resource
    private SysLogWorkService logWorkService;

    @Override
    public QueryWrapper<AgvTrkYfEntity> getWrapper(Map<String, Object> params) {
        return null;
    }

    @Override
    public AgvTrkYfPostDTO getPostYfTrk() {
        //1.获取需下发的任务
        QueryWrapper<AgvTrkYfEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(AgvTrkYfEntity::getStatus, 0)
                .orderBy(true, true, AgvTrkYfEntity::getCreateDate)
                .last("limit 1");
        AgvTrkYfEntity agvTrkYF = baseDao.selectOne(qw);
        if (agvTrkYF == null) {
            return null;
        }
        String location = agvTrkYF.getLocations();
        AgvTrkYfPostDTO postInfo = new AgvTrkYfPostDTO();
//        taskCode
        postInfo.setTask_code(agvTrkYF.getTaskCode());
//        taskType
        postInfo.setTask_type(agvTrkYF.getTaskType());
//        locations需要特殊处理(将字符串拆分后用List<String>传输)
        postInfo.setLocations(Arrays.asList(location.split("#")));
        postInfo.setData_source(agvTrkYF.getDataSource());
        postInfo.setTask_grade(agvTrkYF.getTaskGrade());
//        容器条码
        postInfo.setContainer_code(agvTrkYF.getContainerCode());
        postInfo.setAdditive_info(agvTrkYF.getAdditiveInfo());
        postInfo.setRemark(agvTrkYF.getRemark());
        return postInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void yfTrkScan(TrkEntity wcsTrk) {
//        0.解析任务
        if (wcsTrk == null) {
            return;
        }
        String workName = "[流程-2]任务扫描-YF";
        String workProc = "AgvTrkYfServiceImpl.yfTrkScan";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg;
//        1.通过trkId尝试获取搬送任务是否存在
        AgvTrkYfEntity agvTrkYfEntity = baseDao.selectById(wcsTrk.getTrkId());
        if (agvTrkYfEntity != null) {
            //记录日志并返回
            pCode = "yfTrkScan_001";
            pMsg = "任务扫描异常!wcs任务[" + wcsTrk.getTrkId() + "]已存在!";
            logWorkService.workLogging(workName, wcsTrk.getContNo(), pCode, pMsg, "", workProc, WcsConstants.WCS_USER_NAME, 10L);
            return;
        }
        String contNo = wcsTrk.getContNo();
        String taskCode = contNo + System.currentTimeMillis();
        String taskType = WcsConstants.TRK_TYPE_IN.equals(wcsTrk.getTrkType()) ? "入库" : "出库";
        String locations = wcsTrk.getFrmPos() + "#" + wcsTrk.getToPos();
//        2.写入agv_trk_yf数据
        AgvTrkYfEntity agvTrkYfNew = new AgvTrkYfEntity();
        agvTrkYfNew.setTrkId(wcsTrk.getTrkId());
        agvTrkYfNew.setContainerCode(contNo);
        agvTrkYfNew.setTaskCode(taskCode);
        agvTrkYfNew.setTaskType(taskType);
        agvTrkYfNew.setTaskGrade(WcsConstants.TRK_PRTY_DEF);
        agvTrkYfNew.setLocations(locations);
        agvTrkYfNew.setDataSource(WcsConstants.WCS_USER_NAME);
        agvTrkYfNew.setCreator(WcsConstants.WCS_USER_ID);
        agvTrkYfNew.setUpdater(WcsConstants.WCS_USER_ID);
        baseDao.insert(agvTrkYfNew);
//        3.更新wcs_trk数据
        pMsg = "托盘[" + contNo + "]生成[YF-AGV]搬送任务！关联ID[" + agvTrkYfNew.getId() + "]";
        wcsTrk.setTrkSt(WcsConstants.TRK_STATUS_RUNNING);
        wcsTrk.setComments(pMsg);
        wcsTrk.setUpdateDate(new Date());
        trkService.updateById(wcsTrk);
        logWorkService.workLogging(workName, wcsTrk.getContNo(), pCode, pMsg, "", workProc, "WCS", 0);
    }

    @Override
    public AgvTrkYfEntity getAgvTryByTaskCode(String taskCode) {
        QueryWrapper<AgvTrkYfEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(AgvTrkYfEntity::getTaskCode, taskCode)
                .last("limit 1");
        return baseDao.selectOne(qw);
    }

    @Override
    public void agvTrkHandle(AgvTrkYfPostDTO dto, RcsResultYF response) {
//        1.判断任务是否下发成功
        int code = response.getCode();
        String msg = response.getMessage();
//        2.成功下发更新任务状态为执行中,失败则记录失败原因

//        3.定义状态
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "托盘[" + dto.getContainer_code() + "]搬送任务下发成功!任务编号[" + dto.getTask_code() + "]";
        int status;
        if (code == 0) {
            status = 1;
//            成功下发更新[wcs_trk]任务状态
        } else {
            status = 9;
            pCode = "agvTrkHandle_001";
            pMsg = "料箱[" + dto.getContainer_code() + "]搬送任务下发失败![YF]反馈异常:" + msg;
        }
//        开始时间-start
        Instant start = Instant.now();
//        4.条件更新语句
        UpdateWrapper<AgvTrkYfEntity> uw = new UpdateWrapper<>();
        uw.lambda().set(AgvTrkYfEntity::getStatus, status)
                .set(AgvTrkYfEntity::getRemark, msg)
                .set(AgvTrkYfEntity::getUpdater, WcsConstants.WCS_USER_ID)
                .set(AgvTrkYfEntity::getUpdateDate, new Date())
                .eq(AgvTrkYfEntity::getTaskCode, dto.getTask_code());
        baseDao.update(null, uw);
//        结束时间-end
        Instant end = Instant.now();
//        5.日志记录
        String workName = "[流程-3]任务下发-YF";
        String workProc = "AgvTrkHkServiceImpl.agvTrkHandle";
//        计算耗时
        Duration times = Duration.between(start, end);
        logWorkService.workLogging(workName, dto.getContainer_code(), pCode, pMsg, "", workProc, WcsConstants.WCS_USER_NAME, times.toMillis());
    }

    @Override
    public void updateAgvTrkByContNo(String contNo) {
        QueryWrapper<AgvTrkYfEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(AgvTrkYfEntity::getContainerCode, contNo)
//                .eq(AgvTrkYfEntity::getStatus, RcsConstants.TASK_STATUS_DONE)
                .last("limit 1");
        AgvTrkYfEntity AgvTrkYfEntity = baseDao.selectOne(qw);
//        1.转移历史表
        baseDao.backupAgvTrk(contNo);
        baseDao.deleteById(AgvTrkYfEntity);
    }
}
